package com.example.studentknowledge.repository;

import com.example.studentknowledge.entity.Article;
import com.example.studentknowledge.entity.Category;
import com.example.studentknowledge.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 文章Repository接口
 */
@Repository
public interface ArticleRepository extends JpaRepository<Article, Long> {
    
    /**
     * 根据状态查找文章
     */
    @Query("SELECT a FROM Article a WHERE a.status = :status ORDER BY a.publishedAt DESC")
    Page<Article> findByStatus(@Param("status") Article.Status status, Pageable pageable);
    
    /**
     * 根据作者查找文章
     */
    Page<Article> findByAuthor(User author, Pageable pageable);
    
    /**
     * 根据分类查找文章
     */
    Page<Article> findByCategory(Category category, Pageable pageable);
    
    /**
     * 根据作者和状态查找文章
     */
    Page<Article> findByAuthorAndStatus(User author, Article.Status status, Pageable pageable);
    
    /**
     * 根据分类和状态查找文章
     */
    Page<Article> findByCategoryAndStatus(Category category, Article.Status status, Pageable pageable);
    
    /**
     * 根据标题模糊查询
     */
    @Query("SELECT a FROM Article a WHERE a.title LIKE %:keyword% AND a.status = :status")
    Page<Article> findByTitleContainingAndStatus(@Param("keyword") String keyword, @Param("status") Article.Status status, Pageable pageable);
    
    /**
     * 根据标题或内容模糊查询
     */
    @Query("SELECT a FROM Article a WHERE (a.title LIKE %:keyword% OR a.content LIKE %:keyword%) AND a.status = :status")
    Page<Article> findByTitleOrContentContainingAndStatus(@Param("keyword") String keyword, @Param("status") Article.Status status, Pageable pageable);
    
    /**
     * 获取热门文章（按浏览量排序）
     */
    @Query("SELECT a FROM Article a WHERE a.status = 'PUBLISHED' ORDER BY a.viewCount DESC")
    List<Article> findPopularArticles(Pageable pageable);
    
    /**
     * 获取最新文章
     */
    @Query("SELECT a FROM Article a WHERE a.status = 'PUBLISHED' ORDER BY a.publishedAt DESC")
    List<Article> findLatestArticles(Pageable pageable);
    
    /**
     * 获取推荐文章（按点赞数和浏览量综合排序）
     */
    @Query("SELECT a FROM Article a WHERE a.status = 'PUBLISHED' ORDER BY (a.likeCount * 2 + a.viewCount) DESC")
    List<Article> findRecommendedArticles(Pageable pageable);
    
    /**
     * 根据时间范围查找文章
     */
    @Query("SELECT a FROM Article a WHERE a.publishedAt BETWEEN :startDate AND :endDate AND a.status = 'PUBLISHED' ORDER BY a.publishedAt DESC")
    List<Article> findByPublishedAtBetween(@Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate);
    
    /**
     * 根据发布时间范围查找文章（分页）
     */
    @Query("SELECT a FROM Article a WHERE a.publishedAt BETWEEN :startDate AND :endDate AND a.status = 'PUBLISHED' ORDER BY a.publishedAt DESC")
    Page<Article> findByPublishedAtBetween(@Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate, Pageable pageable);
    
    /**
     * 增加文章浏览量
     */
    @Modifying
    @Query("UPDATE Article a SET a.viewCount = a.viewCount + 1 WHERE a.id = :id")
    void incrementViewCount(@Param("id") Long id);
    
    /**
     * 增加文章点赞数
     */
    @Modifying
    @Query("UPDATE Article a SET a.likeCount = a.likeCount + 1 WHERE a.id = :id")
    void incrementLikeCount(@Param("id") Long id);
    
    /**
     * 减少文章点赞数
     */
    @Modifying
    @Query("UPDATE Article a SET a.likeCount = a.likeCount - 1 WHERE a.id = :id AND a.likeCount > 0")
    void decrementLikeCount(@Param("id") Long id);
    
    /**
     * 更新文章评论数
     */
    @Modifying
    @Query("UPDATE Article a SET a.commentCount = (SELECT COUNT(c) FROM Comment c WHERE c.article.id = a.id) WHERE a.id = :id")
    void updateCommentCount(@Param("id") Long id);
    
    /**
     * 更新文章收藏数
     */
    @Modifying
    @Query("UPDATE Article a SET a.favoriteCount = (SELECT COUNT(f) FROM Favorite f WHERE f.article.id = a.id) WHERE a.id = :id")
    void updateFavoriteCount(@Param("id") Long id);
    
    /**
     * 统计已发布文章总数
     */
    @Query("SELECT COUNT(a) FROM Article a WHERE a.status = 'PUBLISHED'")
    Long countPublishedArticles();
    
    /**
     * 统计用户发布的文章数
     */
    @Query("SELECT COUNT(a) FROM Article a WHERE a.author = :author AND a.status = 'PUBLISHED'")
    Long countByAuthorAndStatus(@Param("author") User author);
    
    /**
     * 统计分类下的文章数
     */
    @Query("SELECT COUNT(a) FROM Article a WHERE a.category = :category AND a.status = 'PUBLISHED'")
    Long countByCategoryAndStatus(@Param("category") Category category);
    
    /**
     * 根据作者和分类查找文章
     */
    Page<Article> findByAuthorAndCategory_Id(User author, Long categoryId, Pageable pageable);
    
    /**
     * 根据作者和状态和分类查找文章
     */
    Page<Article> findByAuthorAndStatusAndCategory_Id(User author, Article.Status status, Long categoryId, Pageable pageable);
    
    /**
     * 根据作者和标题模糊查询
     */
    Page<Article> findByAuthorAndTitleContainingIgnoreCase(User author, String keyword, Pageable pageable);
    
    /**
     * 根据作者和状态和标题模糊查询
     */
    Page<Article> findByAuthorAndStatusAndTitleContainingIgnoreCase(User author, Article.Status status, String keyword, Pageable pageable);
    
    /**
     * 根据作者和分类和标题模糊查询
     */
    Page<Article> findByAuthorAndCategory_IdAndTitleContainingIgnoreCase(User author, Long categoryId, String keyword, Pageable pageable);
    
    /**
     * 根据作者和状态和分类和标题模糊查询
     */
    Page<Article> findByAuthorAndStatusAndCategory_IdAndTitleContainingIgnoreCase(User author, Article.Status status, Long categoryId, String keyword, Pageable pageable);
}